package com.evil.application.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evil.account.api.RemoteUserEnterpriseService;
import com.evil.account.api.RemoteUserService;
import com.evil.application.api.RemoteApplicationImportTemplateService;
import com.evil.application.enums.ImportTemplateTypeEnum;
import com.evil.application.mapper.ApplicationImportTemplateMapper;
import com.evil.application.mapper.ApplicationInfoMapper;
import com.evil.application.pojo.dto.template.UploadTemplateReqDTO;
import com.evil.application.pojo.dto.template.imp.*;
import com.evil.application.pojo.entity.ApplicationImportTemplate;
import com.evil.application.pojo.entity.ApplicationInfo;
import com.evil.application.service.ApplicationImportTemplateService;
import com.evil.application.util.ApplicationUtil;
import com.evil.common.account.util.LoginUtil;
import com.evil.common.application.util.ApplicationRedisKeyUtil;
import com.evil.common.core.enums.RCodeEnum;
import com.evil.common.core.enums.SwitchEnum;
import com.evil.common.core.exception.BusinessException;
import com.evil.common.core.util.RedisUtil;
import com.evil.common.file.constant.OssConstant;
import com.evil.common.file.dto.FileRespDTO;
import com.evil.common.file.dto.UploadReqDTO;
import com.evil.common.file.dto.xml.XmlNodeTreeRespDTO;
import com.evil.common.file.util.XmlUtil;
import com.evil.file.api.RemoteFileService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 导入模板表
 *
 * @author liyang
 * @date 2023-04-06 17:56
 */
@Slf4j
@RestController
@AllArgsConstructor
public class ApplicationImportTemplateServiceImpl extends ServiceImpl<ApplicationImportTemplateMapper, ApplicationImportTemplate>
        implements ApplicationImportTemplateService, RemoteApplicationImportTemplateService {

    private final LoginUtil loginUtil;

    private final RedisUtil redisUtil;

    private final ApplicationInfoMapper applicationInfoMapper;

    private final RemoteUserEnterpriseService remoteUserEnterpriseService;

    private final RemoteUserService remoteUserService;

    private final RemoteFileService remoteFileService;

    private final ApplicationLogServiceImpl applicationLogService;

    @Override
    public int updateBatch(List<ApplicationImportTemplate> list) {
        return baseMapper.updateBatch(list);
    }

    @Override
    public int batchInsert(List<ApplicationImportTemplate> list) {
        return baseMapper.batchInsert(list);
    }

    /**
     * 获取打印模板列表
     *
     * @param importTemplateListReqDTO templateListReqDTO
     * @return List
     */
    @Override
    public List<ImportTemplateRespDTO> list(ImportTemplateListReqDTO importTemplateListReqDTO) {
        importTemplateListReqDTO.setEnterpriseId(loginUtil.getParamEnterpriseId(importTemplateListReqDTO.getEnterpriseId()));
        // 如果当前登录用户不是管理员，看不到任何模板
        if (!remoteUserEnterpriseService.enterpriseManager(loginUtil.getLoginUserEnterprise())) {
            return new ArrayList<>();
        }
        ApplicationInfo applicationInfo = applicationInfoMapper.findByKey(importTemplateListReqDTO.getApplicationKey());
        importTemplateListReqDTO.setApplicationId(applicationInfo.getApplicationId());
        return baseMapper.importTemplateList(importTemplateListReqDTO).stream()
                .map(e -> {
                    ImportTemplateRespDTO temp = BeanUtil.copyProperties(e, ImportTemplateRespDTO.class);
                    temp.setCreator(remoteUserService.findBaseById(e.getCreatorId()));
                    return temp;
                }).collect(Collectors.toList());
    }

    /**
     * 新增打印模板
     *
     * @param saveImportTemplateReqDTO addUploadTemplateReqDTO
     */
    @Override
    public void save(SaveImportTemplateReqDTO saveImportTemplateReqDTO) {
        Long enterpriseId = loginUtil.getLoginEnterpriseId();
        ApplicationInfo applicationInfo = applicationInfoMapper.findByKey(saveImportTemplateReqDTO.getApplicationKey());

        // 检查是否是管理员
        remoteUserEnterpriseService.checkEnterpriseManager(loginUtil.getLoginUserEnterprise());

        ImportTemplateTypeEnum templateTypeEnum = ImportTemplateTypeEnum.findById(saveImportTemplateReqDTO.getTemplateType());
        // 获取文件
        FileRespDTO file = remoteFileService.findBaseByFileCode(saveImportTemplateReqDTO.getFileCode());

        ApplicationImportTemplate importTemplate;
        if (saveImportTemplateReqDTO.getImportTemplateId() != null) {
            // 校验模板是否存在
            importTemplate = baseMapper.findById(saveImportTemplateReqDTO.getImportTemplateId());
        } else {
            importTemplate = new ApplicationImportTemplate();
            // 生成key
            String templateKey = ApplicationUtil.generateKey(key -> this.baseMapper.isExistByKey(key).isPresent());
            importTemplate.setTemplateKey(templateKey);
        }

        importTemplate.setEnterpriseId(enterpriseId);
        importTemplate.setApplicationId(applicationInfo.getApplicationId());
        importTemplate.setTemplateType(saveImportTemplateReqDTO.getTemplateType());
        importTemplate.setTemplateName(saveImportTemplateReqDTO.getFileName());
        importTemplate.setFileId(file.getFileId());
        applicationLogService.saveAndCheck(this.baseMapper, ApplicationImportTemplate::getImportTemplateId, importTemplate);
    }

    /**
     * 重命名打印模板
     *
     * @param renameImportTemplateReqDTO templateRenameReqDTO
     */
    @Override
    public void rename(RenameImportTemplateReqDTO renameImportTemplateReqDTO) {
        // 检查是否是管理员
        remoteUserEnterpriseService.checkEnterpriseManager(loginUtil.getLoginUserEnterprise());

        ApplicationImportTemplate applicationImportTemplate = this.baseMapper.findById(renameImportTemplateReqDTO.getImportTemplateId());
        // 检查企业
        loginUtil.checkEnterpriseId(applicationImportTemplate.getEnterpriseId());

        applicationImportTemplate.setTemplateName(renameImportTemplateReqDTO.getTemplateName());

        applicationLogService.saveAndCheck(this.baseMapper, ApplicationImportTemplate::getImportTemplateId, applicationImportTemplate);
    }

    /**
     * 删除打印模板
     *
     * @param deleteImportTemplateReqDTO deleteTemplateReqDTO
     */
    @Override
    public void delete(DeleteImportTemplateReqDTO deleteImportTemplateReqDTO) {
        // 检查是否是管理员
        remoteUserEnterpriseService.checkEnterpriseManager(loginUtil.getLoginUserEnterprise());

        ApplicationImportTemplate applicationImportTemplate = this.baseMapper.findById(deleteImportTemplateReqDTO.getImportTemplateId());

        applicationImportTemplate.setIsDeleted(SwitchEnum.YES.getId());

        applicationLogService.saveAndCheck(this.baseMapper, ApplicationImportTemplate::getImportTemplateId, applicationImportTemplate);
    }

    /**
     * 打印模板详情
     *
     * @param importTemplateDetailReqDTO templateDetailReqDTO
     * @return TemplateRespDTO
     */
    @Override
    public ImportTemplateRespDTO detail(ImportTemplateDetailReqDTO importTemplateDetailReqDTO) {
        return BeanUtil.copyProperties(this.baseMapper.findById(importTemplateDetailReqDTO.getImportTemplateId()), ImportTemplateRespDTO.class);
    }

    /**
     * 上传打印模板
     *
     * @param uploadTemplateReqDTO uploadTemplateReqDTO
     */
    @Override
    public FileRespDTO upload(UploadTemplateReqDTO uploadTemplateReqDTO) {
        ImportTemplateTypeEnum.findById(uploadTemplateReqDTO.getTemplateType());

        // 检查是否是管理员
        remoteUserEnterpriseService.checkEnterpriseManager(loginUtil.getLoginUserEnterprise());

        ApplicationInfo applicationInfo = applicationInfoMapper.findByKey(uploadTemplateReqDTO.getApplicationKey());
        // 检查企业
        loginUtil.checkEnterpriseId(applicationInfo.getEnterpriseId());

        // 上传文件 新增file数据
        UploadReqDTO uploadReqDTO = new UploadReqDTO();
        uploadReqDTO.setEnterpriseId(uploadTemplateReqDTO.getEnterpriseId());
        uploadReqDTO.setFile(uploadTemplateReqDTO.getFile());
        uploadReqDTO.setType(uploadTemplateReqDTO.getType());
        uploadReqDTO.setUserId(uploadTemplateReqDTO.getUserId());
        uploadReqDTO.setAllowContentType(null);
        uploadReqDTO.setAllowMaxSize(OssConstant.UPLOAD_FILE_SIZE);
        return remoteFileService.uploadFile(uploadReqDTO);
    }

    /**
     * 下载打印模板
     *
     * @param downloadImportTemplateReqDTO downloadTemplateReqDTO
     * @return FileRespDTO
     */
    @Override
    public FileRespDTO download(DownloadImportTemplateReqDTO downloadImportTemplateReqDTO) {
        // 检查是否是管理员
        remoteUserEnterpriseService.checkEnterpriseManager(loginUtil.getLoginUserEnterprise());
        // 校验模板是否存在
        ApplicationImportTemplate applicationImportTemplate = this.baseMapper.findById(downloadImportTemplateReqDTO.getImportTemplateId());
        if (applicationImportTemplate.getFileId() == null) {
            throw new BusinessException(RCodeEnum.ERROR, "模板文件不存在");
        }

        return remoteFileService.findBaseByFileId(applicationImportTemplate.getFileId());
    }

    /**
     * 读取xml文件
     *
     * @param fileCode fileCode
     * @return XmlNodeTreeRespDTO 列表
     */
    @Override
    public List<XmlNodeTreeRespDTO> readXmlNode(String fileCode) {
        // redis缓存中获取
        String key = ApplicationRedisKeyUtil.importTemplateFileXmlNodeKey(fileCode);
        Object o = redisUtil.get(key);
        if (o instanceof List) {
            return ((List<?>) o).stream().map(e -> (XmlNodeTreeRespDTO) e).collect(Collectors.toList());
        }
        byte[] bytes = remoteFileService.getFileByteByFileCode(fileCode);
        List<XmlNodeTreeRespDTO> nodeTree = XmlUtil.analysisXmlFile(bytes);
        // 缓存
        log.info("读取xml文件 | cache result: {}", redisUtil.set(key, nodeTree));
        return nodeTree;
    }

    /**
     * 导入模板数据
     *
     * @param importTemplateReqDTO importTemplateReqDTO
     */
    @Override
    public FileRespDTO importTemplate(ImportTemplateReqDTO importTemplateReqDTO) {
        return null;
    }
}
